#region File Header
//----------------------------------------------------------------
// Copyright (C) 2002 Stefan Kyntchev
// All rights reserved.
//
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY 
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT 
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR 
// FITNESS FOR A PARTICULAR PURPOSE.
//----------------------------------------------------------------
#endregion File Header

namespace FlashBack.Web
{
	using System;
	using AirWeb.WebControls.TreeControl;
	using System.IO;
	using System.Collections;
	using System.Web;
	using System.Web.UI;
	using System.Web.UI.WebControls;
	using System.Web.UI.HtmlControls;
	using AirWeb.DirectoryMgr;
	using AirWeb.ApplicationTools;
	using AirWeb.Security;
	using AirWeb.Security.FileSecurity;

	public class AccessItem : NodeItem
	{
		private string m_Directory;
		private string m_Name;
		private bool m_Accesible;
		private bool m_Public;
		private bool m_Checked = false;
		private string m_FullPath;

		private ArrayList m_accessList = new ArrayList();

		public override void Render(ControlCollection i_context)
		{
			// Add a separator
			Label l = new Label();
			l.Text = " ";
			i_context.Add(l);

			// Add the link
			Label a = new Label();
			a.Text = " " + m_Name;
			a.Style.Add("font-family","Verdana");
			a.Style.Add("font-size","9pt");

			AccessItem parent = (AccessItem)Owner.ParentNode.nodeItem;
			if(parent == null || !parent.IsAccesible)
			{
				CheckBox cb = new CheckBox();
				cb.Checked = true;
				cb.CheckedChanged += new System.EventHandler(this.OnCheckChanged);
				cb.Attributes["Path"] = m_Directory;
				cb.AutoPostBack = true;
				cb.ID = "acb_" + Owner.NodeID.ToString();

				if(m_Accesible)
				{
					Checked = true;
				}
				else
				{
					a.Style.Add("color","red");
				}

				cb.Checked = Checked;
				i_context.Add(cb);
			}

			Image i = new Image();


			if(m_Directory.IndexOf("Movie") != -1)
			{
				i.ImageUrl = "images/movie.gif";
			}
			else if(IsPublic)
			{
				i.ImageUrl = "images/bo.gif";
			}
			else if(Owner.Expanded)
			{
				i.ImageUrl = "images/Camera.gif";
			}
			else
			{
				i.ImageUrl = "images/Camera.gif";
			}
			
			i_context.Add(i);
			i_context.Add(a);
		}

		/// <summary>
		/// Hadler for OnCheck event for all checkboxes
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		public void OnCheckChanged(object sender, EventArgs e)
		{	
			CheckBox cb = (CheckBox)sender;
			Checked = cb.Checked;

			// This will populate the m_accessList with all the chacked nodes
			GetAllowedAccess();	
		
			// Now call the TreeModel to update the security
			ManageAccessTreeModel m = (ManageAccessTreeModel)Owner.MyTreeControl.TreeModel;
			m.SetAccessRights(m_accessList);
		}

		/// <summary>
		/// This is a delegate handler invoked by AirWeb.WebControls.TreeControl.TreeNode.Traverse
		/// </summary>
		/// <param name="i_node"></param>
		/// <returns></returns>
		public bool TraverseHandler(AirWeb.WebControls.TreeControl.TreeNode i_node)
		{
			AccessItem i = (AccessItem)i_node.nodeItem;

			if(i.Checked)
				m_accessList.Add(i.DirectoryPath);

			return true;
		}

		/// <summary>
		/// Traverses the tree to collect all nodes that are checked
		/// </summary>
		public void GetAllowedAccess()
		{
			AirWeb.WebControls.TreeControl.TreeNode.m_traverseCallback = new TraverseCallback(this.TraverseHandler);

			// This will populate the m_accessList with all the chacked nodes
			AirWeb.WebControls.TreeControl.TreeNode.Traverse(Owner.RootNode);
		}

		public string DirectoryPath
		{
			get
			{
				return m_Directory;
			}
			set
			{
				m_Directory = value;
				m_Directory = m_Directory.Replace('\\','/');
			}
		}

		public string Name
		{
			get
			{
				return m_Name;
			}
			set
			{
				m_Name = value;
			}
		}

		public bool IsAccesible
		{
			get
			{
				return m_Accesible;
			}
			set
			{
				m_Accesible = value;
			}
		}

		public bool Checked
		{
			get
			{
				return m_Checked;
			}
			set
			{
				m_Checked = value;
			}
		}

		public bool IsPublic
		{
			get
			{
				return m_Public;
			}
			set
			{
				m_Public = value;
			}
		}
		public string FullDirectoryPath
		{
			get { return m_FullPath; }
			set { m_FullPath = value; }
		}
	}

    /// <summary>
    ///    .
    /// </summary>
    public class ManageAccessTreeModel : ITreeControlModel
    {
		private string path = "";
		private HttpContext m_context;
		private AirWeb.Security.Role m_currentRole;
		private AirWeb.WebControls.TreeControl.TreeNode m_rootNode;

        public ManageAccessTreeModel()
        {
            //
            // TODO: Add Constructor Logic here
            //
        }

		public void BuildModel ( AirWeb.WebControls.TreeControl.TreeNode l ) 
		{
			// Save our root node
			m_rootNode = l;

			DirectoryInfo dir = new DirectoryInfo(path);

			if(!dir.Exists)
			{
				return;
			}

			AccessItem di = new AccessItem();
			di.FullDirectoryPath = path;
			l.nodeItem = di;
		
			AddChildNodes(l);
		}

		public void SetPath( string p )
		{
			path = p;
		}

		public void SetRole( string i_Role )
		{
			m_currentRole = AirWeb.Security.SecurityMgr.Instance.GetRoleByName(i_Role);

			if( m_currentRole == null)
			{
				throw new ArgumentException("Invalid Role name was provided");
			}		
		}

		public void SetContext( HttpContext i_c )
		{
			m_context = i_c;
		}

		public void SetAccessRights(ArrayList i_accesslist)
		{
			m_currentRole.RemoveAllAllowRights();
			foreach(string path in i_accesslist)
			{
				FilePathResource fpr = new FilePathResource(path);
				m_currentRole.AddAllowRight(new AirWeb.Security.Right(fpr, AirWeb.Security.Right.AccessLevel.Read));
			}

			AirWeb.Security.SecurityMgr.Instance.Serialize();

			// Ask our owning control to rebuild itself
			m_rootNode.MyTreeControl.BuildControlContent();
		}

		public void AddChildNodes(AirWeb.WebControls.TreeControl.TreeNode l)
		{
			if(!l.Expanded)
				return;

			DirectoryLister dirlister = new DirectoryLister();
			dirlister.Comparer = new FileComparer(CompareBy.CreationDate,SortOrder.Ascending);
			
			AccessItem diritem = (AccessItem)l.nodeItem;

			ArrayList dl = dirlister.ListDirectories(diritem.FullDirectoryPath,0);

			DirectoryHelper m_dirHelper = new DirectoryHelper();
			
			if(dl.Count != 0)
			{
				for(int a= 0; a != dl.Count; a++ )
				{
					DirectoryInfo d = (DirectoryInfo)dl[a];

					String dirname = d.Name;
					String content = "";
					AccessItem di = new AccessItem();

					// Set the "Public" folder at the end of the list
					if(dirname == "Public")
					{
						if( a != dl.Count-1)
						{
							dl.RemoveAt(a);
							dl.Add(d);
							--a;
							continue;
						}
						else
						{
							di.IsPublic = true;
						}
					}

					int numfiles =  d.GetFiles().Length;
					int numdirs =  d.GetDirectories().Length;

					if(numfiles == 0 && numdirs == 0)
					{
						content = "( No Pictures )";
					}

					if( numfiles != 0)
					{
						if(dirname.IndexOf("Movies") != -1)
						{
							content = " (" + numfiles + " Movies" + ")";	
						}
						else
						{
							content = " (" + numfiles + " Pictures" + ")";	
						}
					}
					
					dirname += content;
					
					string relPath = m_dirHelper.ReverseMapPath(d.FullName,m_dirHelper.OriginalsVirtualRoot);

					di.DirectoryPath = relPath;
					di.Name = dirname;
					di.FullDirectoryPath = d.FullName;
					
					FilePathResource fpr = new FilePathResource(relPath);
					if (m_currentRole.HasAtLeastRight(new AirWeb.Security.Right(fpr, AirWeb.Security.Right.AccessLevel.Read)))
					{
						di.IsAccesible = true;
					}

					AirWeb.WebControls.TreeControl.TreeNode child = new AirWeb.WebControls.TreeControl.TreeNode(l);
					child.nodeItem = di;

					if(numdirs > 0)
						child.HasChildren = true;

					l.AddChild(child);
					
					AddChildNodes(child);
				}				
			}
		}
	}	
}
